/**
 * Copyright 2006 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy
 * of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package com.google.appsforyourdomain.provisioning;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * This is a Util class with methods to post HTTP request
 * and parse XML.
 *
 */
public class AppsUtil {

 /**
  * Posts the specified postContent to the urlString and
  * returns a JDOM Document object containing the XML response.
  * 
  * @param urlString URL destination
  * @param postContent XML request
  * @return a JDOM Document object containing the XML response
  */
  public static Document postHttpRequest(String urlString, String postContent) 
      throws AppsForYourDomainException {
    try {
      
      // Send content
      final HttpClient client = new HttpClient();
      PostMethod method = new PostMethod(urlString);
      StringRequestEntity sre = 
          new StringRequestEntity(postContent, "text/xml", "UTF-8");
      method.setRequestEntity(sre);
      client.executeMethod(method);
      
      // Get response
      final SAXBuilder builder = new SAXBuilder();
      BufferedReader rd = new BufferedReader(
          new InputStreamReader(method.getResponseBodyAsStream()));
      final Document doc = builder.build(rd);
      return doc;
    } catch (IOException e) {
      
      // error in URL Connection or reading response
      throw new ConnectionException(e.getMessage());
    } catch (JDOMException e) {
      
      // error in converting to JDOM Document
      throw new ParseException(e.getMessage());
    }
  }
          
  /**
   * Parses a JDOM Document and returns the first element that matches the
   * specified path.
   * 
   * @param doc JDOM document
   * @param path XPATH to the element
   * @return the value of the element
   */
  public static String parseXml(Document doc, String path) 
      throws AppsForYourDomainException {
    try {
      XPath statusXPath = XPath.newInstance(path);
      Object node = statusXPath.selectSingleNode(doc);
      if (node == null) {
        return ""; // Did not find any nodes matching in doc
      }
      Element element;
      if (node instanceof Element) {
        element = (Element) node;
        return element.getText();
      } else {
        return ""; // Returned node has unexpected type
      }
    } catch (JDOMException e) {
      throw new ParseException(e.getMessage());
    }
  }
      
  /**
   * Parses a JDOM Document and returns a list of all matching elements that
   * match the specified path.
   * 
   * @param doc JDOM document
   * @param path XPATH to the element
   * @return a list of all matching element values
   */
  public static List<String> parseXmlMultipleNodes(Document doc, String path) 
      throws AppsForYourDomainException {
    try {
      List nodes = XPath.selectNodes(doc, path);
      List<String> infoList = new ArrayList<String>();
      for (Object node : nodes) {
        if (node instanceof Element) {
          Element element = (Element) node;
          infoList.add(element.getText());
        }
      }
      return infoList;
    } catch (JDOMException e) {
      throw new ParseException(e.getMessage());
    }
  }
}
